﻿using AutoMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using MyCompany.MyProject.Common;
using MyCompany.MyProject.Common.Caches;
using MyCompany.MyProject.Common.Helper;
using MyCompany.MyProject.Common.HttpContextUser;
using MyCompany.MyProject.Common.Option;
using MyCompany.MyProject.Common.UtilIity;
using MyCompany.MyProject.Extensions.Helper;
using MyCompany.MyProject.IService;
using MyCompany.MyProject.Model;
using MyCompany.MyProject.Model.DTO;
using MyCompany.MyProject.Model.Logs;
using MyCompany.MyProject.Model.Models;
using MyCompany.MyProject.Repository.UnitOfWork;
using MyCompany.MyProject.Service;
using MyCompany.MyProject.WebApi.ModelDto.UserDto;
using Newtonsoft.Json;
using System.Linq.Expressions;

namespace MyCompany.MyProject.WebApi.Controllers;

/// <summary>
/// 测试控制器
/// </summary>
public class UserController : BasePermissionApiController
{
    private readonly IBaseService<Role> _roleService;
    private readonly IUserService _userService;
    private readonly IMapper _mapper;
    private readonly IUser _user;
    private readonly IDepartmentService _departmentService;
    private readonly IUserRoleService _userRoleService;
    private readonly IUnitOfWorkManage _unitOfWorkManage;
    private readonly ILogger<UserController> _logger;
    private readonly IWebHostEnvironment _env;
    private readonly IOptions<RedisOption> _redisOptions;
    private readonly ICaching _caching;
    private readonly IBaseService<AuditSqlLog> _auditLog;

    /// <summary>
    /// 这个是为了测试属性注入使用的
    /// </summary>
    public IBaseService<Role>? RoleServiceObj { get; set; }
    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="roleService"></param>
    /// <param name="userService"></param>
    /// <param name="redisOptions"></param>
    /// <param name="caching"></param>
    /// <param name="auditLog"></param>
    /// <param name="mapper"></param>
    /// <param name="user"></param>
    /// <param name="departmentService"></param>
    /// <param name="userRoleService"></param>
    /// <param name="unitOfWorkManage"></param>
    /// <param name="logger"></param>
    /// <param name="env"></param>
    public UserController(IBaseService<Role> roleService, IUserService userService, IMapper mapper, IUser user,
        IDepartmentService departmentService, IUserRoleService userRoleService, IUnitOfWorkManage unitOfWorkManage,
        ILogger<UserController> logger, IWebHostEnvironment env,
        IOptions<RedisOption> redisOptions, ICaching caching, IBaseService<AuditSqlLog> auditLog)
    {
        _roleService = roleService;
        _userService = userService;
        _mapper = mapper;
        _user = user;
        _departmentService = departmentService;
        _userRoleService = userRoleService;
        _unitOfWorkManage = unitOfWorkManage;
        _logger = logger;
        _env = env;
        _redisOptions = redisOptions;
        _caching = caching;
        _auditLog = auditLog;
    }
    /// <summary>
    /// 测试用户相关功能
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public async Task<IActionResult> TestUser()
    {
        //var userService = new UserService();
        //var userList = await userService.Query();
        var userList = await _userService.Query();
        return Ok(userList);
    }
    /// <summary>
    /// 测试角色
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public async Task<IActionResult> TestRole()
    {
        var roleList = await _roleService.Query();
        Console.WriteLine(_roleService.GetHashCode());
        //var roles = await RoleServiceObj.Query();
        var roles = await _roleService.Query();
        Console.WriteLine(_roleService.GetHashCode());
        return Ok(new { roleList, roles });
    }

    /// <summary>
    /// 测试Appsettings类
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public async Task<IActionResult> TestAppsettings()
    {
        var redisEnable = AppSettings.app("Redis", "Enable");
        var redisConnect = AppSettings.app("Redis:ConnectionString");
        Console.WriteLine($"Enable:{redisEnable},ConnectionString:{redisConnect}");

        var redisOptions = _redisOptions.Value;
        await Task.CompletedTask;
        return Ok(new { redisEnable, redisConnect, redisOptions });
    }

    /// <summary>
    /// 测试缓存
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public async Task<IActionResult> TestCache()
    {
        var cacheKey = "cache-key";
        List<string> cacheKeys = await _caching.GetAllCacheKeysAsync();
        await Console.Out.WriteLineAsync("全部keys -->" + JsonConvert.SerializeObject(cacheKeys));

        await Console.Out.WriteLineAsync("添加一个缓存");
        await _caching.SetStringAsync(cacheKey, "hi laozhang");
        await Console.Out.WriteLineAsync("全部keys -->" + JsonConvert.SerializeObject(await _caching.GetAllCacheKeysAsync()));
        await Console.Out.WriteLineAsync("当前key内容-->" + JsonConvert.SerializeObject(await _caching.GetStringAsync(cacheKey)));

        await Console.Out.WriteLineAsync("删除key");
        await _caching.RemoveAsync(cacheKey);
        await Console.Out.WriteLineAsync("全部keys -->" + JsonConvert.SerializeObject(await _caching.GetAllCacheKeysAsync()));

        return Ok(new { cacheKeys });
    }

    /// <summary>
    /// 测试审计日志
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    [AllowAnonymous]
    public async Task<IActionResult> TestAuditLog()
    {
        // var roleList = await _roleService.Query();
        // var res = await _auditLog.QuerySplit(d=>true);

        TimeSpan timeSpan = DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        var id = timeSpan.TotalSeconds.ObjToLong();
        await _auditLog.AddSplit(new AuditSqlLog()
        {
            Id = id,
            DateTime = DateTime.Now,// Convert.ToDateTime("2023-12-23"),
        });

        var res = await _auditLog.QuerySplit(d => d.DateTime <= DateTime.Now);


        return Ok(res);
    }





    /// <summary>
    /// 分页获取用户列表
    /// </summary>
    /// <param name="pageIndex"></param>
    /// <param name="pageSize"></param>
    /// <param name="key"></param>
    /// <returns></returns>
    [HttpGet]
    public async Task<MessageModel<PageModel<UserVo>>> Get(int pageIndex, int pageSize, string key = "",string age="")
    {   
        if (string.IsNullOrEmpty(key) || string.IsNullOrWhiteSpace(key))
        {
            key = "";
        }
        //var whereExpression 
        Expression<Func<SysUserInfo, bool>> whereExpression = i => true;
        if (!string.IsNullOrEmpty(key))
        {
            whereExpression = whereExpression.And(i => i.Name.Contains(key) || i.RealName.Contains(key));
        }
        if (!string.IsNullOrEmpty(age))
        {
            whereExpression = whereExpression.And(i => i.Age == age.ObjToInt());
        }
        var data = await _userService.QueryPage(whereExpression, pageIndex, pageSize, " Id desc ");

        #region 给用户的角色Id 角色名称 部门名称 部门id赋值

        var allUserRoles = await _userRoleService.Query(d => d.IsDeleted == false);
        var allRoles = await _roleService.Query(d => d.IsDeleted == false);
        var allDepartments = await _departmentService.Query(d => d.IsDeleted == false);

        var userInfo = data.Data;
        foreach (var item in userInfo)
        {
            var currentUserRoles = allUserRoles.Where(d => d.UserId == item.Id).Select(d => d.RoleId).ToList();
            item.RIDs = currentUserRoles;
            item.RoleNames = allRoles.Where(i => currentUserRoles.Contains(i.Id)).Select(i => i.Name).ToList()!;
            var departmentNameAndIds = GetFullDepartmentName( allDepartments, item.DepartmentId);
            item.DepartmentName = departmentNameAndIds.Item1;
            item.Dids = departmentNameAndIds.Item2;
        }

        data.Data = userInfo;
        #endregion

        var res = new MessageModel<PageModel<UserVo>>()
        {
            status = 200,
            success = true,
            msg = "ok",
            response = data.ConvertTo<UserVo>(_mapper)
        };

        return res;
    }

    private (string, List<long>) GetFullDepartmentName(List<Department> departments, long deptId)
    {
        var deptModel = departments.FirstOrDefault(i => i.Id == deptId);
        if (deptModel == null)
            return ("", new List<long>());

        var pids = deptModel.CodeRelationship?.TrimEnd(',').Split(',').Select(i => i.ObjToLong()).ToList();
        pids.Add(deptModel.Id);
        var pNames = departments.Where(d => pids.Contains(d.Id)).ToList().Select(i => i.Name).ToList();
        var fullName = string.Join("/", pNames);
        return (fullName, pids);
    }

    /// <summary>
    /// 新增用户信息
    /// </summary>
    /// <param name="user"></param>
    /// <returns></returns>
    [HttpPost]
    public async Task<MessageModel<string>> Post(UserVo user)
    {
        var data = new MessageModel<string>();
        user.LoginPWD = MD5Helper.MD5Encrypt32(user.LoginPWD);
        user.Remark = _user.Name;
        var id = await _userService.Add(_mapper.Map<SysUserInfo>(user));
        //var id = await _userService.Add(user);
        data.success = id > 0;
        if (data.success)
        {
            data.response = id.ObjToString();
            data.msg = "添加成功";
        }
        return data;
    }

    /// <summary>
    /// 更新用户信息
    /// </summary>
    /// <param name="userVo"></param>
    /// <returns></returns>
    [HttpPut]
    public async Task<MessageModel<string>> Put(UserVo userVo)
    {
        var data = new MessageModel<string>();
        var oldUser = await _userService.QueryById(userVo.Id);
        if (oldUser is not { Id: > 0 })
        {
            return Failed<string>("用户不存在或已被删除");
        }

        try
        {
            //if (userVo.uLoginPWD!=oldUser.uLoginPWD)
            //{
            //    oldUser.uUpdateTime = DateTime.Now;
            //}

            //_mapper.Map(userVo,oldUser);

            _unitOfWorkManage.BeginTran();

            // 无论 Update Or Add 先删除当前用户的全部 U_R 关系
            var userRoles = (await _userRoleService.Query(d => d.UserId == userVo.Id));
            if (userRoles.Any())
            {
                var ids = userRoles.Select(i => i.Id.ToString()).ToArray();
                var isAllDeleted = await _userRoleService.DeleteByIds(ids);
                if (!isAllDeleted)
                {
                    return Failed<string>("服务器更新异常");
                }
            }

            // 然后再执行添加操作
            if (userVo.RIDs.Any())
            {
                var userRolesAdd = new List<UserRole>();
                userVo.RIDs.ForEach(rid => { userRolesAdd.Add(new UserRole() { UserId = userVo.Id, RoleId = rid, IsDeleted = false }); });

                var oldRole = userRoles.Select(s => s.RoleId).OrderBy(i => i).ToArray();
                var newRole = userRolesAdd.Select(s => s.RoleId).OrderBy(i => i).ToArray();
                if (!oldRole.SequenceEqual(newRole))
                {
                    oldUser.UpdateTime = DateTime.Now;
                }

                await _userRoleService.Add(userRolesAdd);
            }

            data.success = await _userService.Update(_mapper.Map<SysUserInfo>( userVo));

            _unitOfWorkManage.CommitTran();

            if (data.success)
            {
                data.msg = "更新成功";
                data.response = oldUser.Id.ObjToString();
            }
        }
        catch (Exception ex)
        {
            _unitOfWorkManage.RollbackTran();
            _logger.LogError(ex, ex.Message);
        }

        return data;
    }


    /// <summary>
    /// 删除用户数据
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    //[HttpDelete("{id}")] // 这个是RESTFull方式，前端请求需要是 /api/user/delete/123
    [HttpDelete]
    public async Task<MessageModel<string>> Delete([FromQuery] long id)
    {
        var data = new MessageModel<string>();
        if (id > 0)
        {
            var userDetail = await _userService.QueryById(id);
            userDetail.IsDelete = true;
            data.success = await _userService.Update((userDetail));
            if (data.success)
            {
                data.msg = "删除成功";
                data.response = userDetail.Id.ObjToString();
            }
        }
        return data;
    }

    /// <summary>
    /// 批量删除
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>
    [HttpDelete]
    public async Task<MessageModel<string>> DeleteMuch([FromBody] long[] ids)
    {
        var data = new MessageModel<string>();
        if (ids.Length > 0)
        {
            var userDetails = await _userService.QueryByIDs(ids);
            foreach (var model in userDetails)
                model.IsDeleted = true;
            data.success = await _userService.Update(userDetails);
            if (data.success)
            {
                data.msg = "删除成功";
                data.response = "";
            }
        }
        return data;
    }

    /// <summary>
    /// 根据数据库数据生成种子数据文件，方便其他环境使用
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public async Task<MessageModel<string>> SaveDataToTsv()
    {
        var data = new MessageModel<string>();
        if (_env.IsDevelopment())
        {
            JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
            };
            var list = await _userService.Query(d => d.IsDeleted == false);
            var json = JsonConvert.SerializeObject(list, jsonSerializerSettings);
            FileHelper.WriteFile(Path.Combine(_env.WebRootPath, "SeedData", "SysUserInfo.tsv"), json, System.Text.Encoding.UTF8);
            data.success = true;
            data.msg = "操作成功";
        }
        else
        {
            data.success = false;
            data.msg = "仅开发环境可用";
        }
        return data;
    }
}
